package account

import (
	"NovelBook/dao"
	"NovelBook/models/db_models"
	"NovelBook/models/res"
	"NovelBook/utils/jwt"
	"context"
	"errors"
	"time"

	"github.com/redis/go-redis/v9"
)

type UserType int

const (
	SUPERUSER UserType = iota
	MANAGER
	WORKER
	BORROWER
)

func LoginByAccount(user res.AccountPassword, userType UserType) (res.UserToken, error) {
	userDB := res.UserInfo{}
	var err error
	switch userType {
	case SUPERUSER:
		err = dao.GetDb().Model(db_models.Superuser{}).Where("account = ?", user.Account).First(&userDB).Error
	case MANAGER:
		err = dao.GetDb().Model(db_models.Manager{}).Where("account = ?", user.Account).First(&userDB).Error
	case WORKER:
		// 只有 worker.state == 1 才能登录
		err = dao.GetDb().Model(db_models.Worker{}).Where("account = ? AND state = ?", user.Account, 1).First(&userDB).Error
	case BORROWER:
		err = dao.GetDb().Model(db_models.Borrower{}).Where("account = ?", user.Account).First(&userDB).Error
	}
	if err != nil {
		return res.UserToken{}, err
	}

	if userDB.Account != user.Account || userDB.Password != user.Password {
		return res.UserToken{}, errors.New("account or password error")
	}

	Token := ""
	switch userType {
	case SUPERUSER:
		Token, err = jwt.GenToken(userDB.ID, jwt.SUPERUSER)
	case MANAGER:
		Token, err = jwt.GenToken(userDB.ID, jwt.MANAGER)
	case WORKER:
		Token, err = jwt.GenToken(userDB.ID, jwt.WORKER)
	case BORROWER:
		Token, err = jwt.GenToken(userDB.ID, jwt.BORROWER)
	}

	if err != nil {
		return res.UserToken{}, errors.New("try again")
	}

	// 设置返回的密码为空
	userDB.Password = ""

	if err := IncVisits(); err != nil {
		return res.UserToken{}, errors.New("redis error")
	}

	return res.UserToken{User: userDB, Token: Token}, nil
}

func LoginByEmail(user res.EmailPassword, userType UserType) (res.UserToken, error) {
	userDB := res.UserInfo{}
	var err error
	switch userType {
	case SUPERUSER:
		err = dao.GetDb().Model(db_models.Superuser{}).Where("email = ?", user.Email).First(&userDB).Error
	case MANAGER:
		err = dao.GetDb().Model(db_models.Manager{}).Where("email = ?", user.Email).First(&userDB).Error
	case WORKER:
		// 只有 worker.state == 1 才能登录
		err = dao.GetDb().Model(db_models.Worker{}).Where("email = ? AND state = ?", user.Email, 1).First(&userDB).Error
	case BORROWER:
		err = dao.GetDb().Model(db_models.Borrower{}).Where("email = ?", user.Email).First(&userDB).Error
	}
	if err != nil {
		return res.UserToken{}, err
	}

	if userDB.Email != user.Email || userDB.Password != user.Password {
		return res.UserToken{}, errors.New("email or password error")
	}

	Token := ""
	switch userType {
	case SUPERUSER:
		Token, err = jwt.GenToken(userDB.ID, jwt.SUPERUSER)
	case MANAGER:
		Token, err = jwt.GenToken(userDB.ID, jwt.MANAGER)
	case WORKER:
		Token, err = jwt.GenToken(userDB.ID, jwt.WORKER)
	case BORROWER:
		Token, err = jwt.GenToken(userDB.ID, jwt.BORROWER)
	}

	if err != nil {
		return res.UserToken{}, errors.New("try again")
	}

	// 设置返回的密码为空
	userDB.Password = ""

	if err := IncVisits(); err != nil {
		return res.UserToken{}, errors.New("redis error")
	}

	return res.UserToken{User: userDB, Token: Token}, nil
}

func IncVisits() error {
	// 增加redis中的访问量
	ctx := context.Background()
	today := time.Now().Format("2006-01-02")
	// TTL设置为今天的剩余时间
	remainingTime := time.Until(time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 23, 59, 59, 0, time.Now().Location()))

	if _, err := dao.Get("visits:" + today); err != nil {
		if err == redis.Nil {
			if err := dao.Set("visits:"+today, 0, remainingTime); err != nil {
				return err
			}
		} else {
			return err
		}
	}
	if err := dao.Rdb.Incr(ctx, "visits:"+today).Err(); err != nil {
		return err
	}
	return nil
}
